package com.cs.framework.common.util;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.cs.framework.common.annotation.NotNull;
import com.cs.framework.common.bo.BoBase;
import com.cs.framework.common.util.ReflectUtils.LoopClassFieldDeal;

/**
 * 常用工具类
 * 
 * @author hedongzhou
 * 
 */
public class CommonUtils {

	/**
	 * 拷贝业务对象属性值
	 * 
	 * @param target
	 *            目标对象
	 * @param copy
	 *            用于拷贝的对象
	 * @param sameParam
	 *            目标对象与拷贝对象共有的属性<br/>
	 *            如果为空，则直接拷贝全部属性，排除createUser、createDate、updateUser 、updateDate
	 */
	public static void copyBoValue(BoBase target, BoBase copy, String... sameParam) {
		if (sameParam == null || sameParam.length == 0) {
			Map<String, Object> copyValueMap = ReflectUtils.getFieldValue(copy);

			Set<String> params = copyValueMap.keySet();

			for (String targetParam : params) {
				if (!StringUtils.equalOne(targetParam, "createUser", "createDate", "updateUser", "updateDate")) {
					Object value = copyValueMap.get(targetParam);

					String setMethod = "set" + targetParam.substring(0, 1).toUpperCase() + targetParam.substring(1);

					try {
						ReflectUtils.doMethod(target, setMethod, value);
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
				}
			}
		} else {
			try {
				ReflectUtils.copyValue(target, copy, sameParam);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 非空校验
	 * 
	 * @param Obj
	 * @return
	 */
	public static void checkNotNull(Object Obj) {
		final Object temp = Obj;

		ReflectUtils.loopClassField(temp.getClass(), new LoopClassFieldDeal() {
			public boolean deal(Field field) {
				NotNull check = field.getAnnotation(NotNull.class);

				if (check != null) {
					field.setAccessible(true);

					Object value = null;
					try {
						value = field.get(temp);
					} catch (Exception e) {
						throwRun(e);
					}

					throwNull(value, check.value());
				}

				return true;
			}
		});
	}

	/**
	 * 判断是否为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		} else if (obj instanceof String && StringUtils.isBlank((String) obj)) {
			return true;
		} else if (obj instanceof List && ContainerUtils.listIsEmpty((List<?>) obj)) {
			return true;
		} else if (obj instanceof Map && ContainerUtils.mapIsEmpty((Map<?, ?>) obj)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否为空
	 * 
	 * @param <T>
	 * @param obj
	 * @return
	 */
	public static <T> boolean isEmpty(T[] obj) {
		if (ArrayUtils.isEmpty(obj)) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否不为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isNotEmpty(Object obj) {
		return !isEmpty(obj);
	}

	/**
	 * 判断是否不为空
	 * 
	 * @param <T>
	 * @param obj
	 * @return
	 */
	public static <T> boolean isNotEmpty(T[] obj) {
		return !isEmpty(obj);
	}

	/**
	 * 如果为空，则抛异常
	 * 
	 * @param obj
	 *            对象
	 * @param errMsg
	 *            错误提示，会在其后面自动加上“不能为空”
	 */
	public static void throwNull(Object obj, String errMsg) {
		if (isEmpty(obj)) {
			throwRun(errMsg + "不能为空");
		}
	}

	/**
	 * 如果为空，则抛异常
	 * 
	 * @param <T>
	 * @param obj
	 *            对象
	 * @param errMsg
	 *            错误提示，会在其后面自动加上“不能为空”
	 */
	public static <T> void throwNull(T[] obj, String errMsg) {
		if (isEmpty(obj)) {
			throw new RuntimeException(errMsg + "不能为空");
		}
	}

	/**
	 * 抛异常
	 * 
	 * @param errMsg
	 *            错误提示
	 * @throws Exception
	 */
	public static void throwExc(String errMsg) throws Exception {
		throw new Exception(errMsg);
	}

	/**
	 * 抛异常
	 * 
	 * @param e
	 *            异常
	 * @throws Exception
	 */
	public static void throwExc(Throwable e) throws Exception {
		throw new Exception(e);
	}

	/**
	 * 抛异常
	 * 
	 * @param errMsg
	 *            错误提示
	 */
	public static void throwRun(String errMsg) {
		throw new RuntimeException(errMsg);
	}

	/**
	 * 抛异常
	 * 
	 * @param e
	 *            异常
	 */
	public static void throwRun(Throwable e) {
		throw new RuntimeException(e);
	}

}
